package zkp

import (
	"bytes"
	"encoding/base64"
	"math/big"

	"github.com/consensys/gnark-crypto/ecc"
	"github.com/consensys/gnark/backend/groth16"
	"github.com/consensys/gnark/frontend"
)

// VerifyProof 验证零知识证明
func VerifyProof(vk groth16.VerifyingKey, proofB64 string, publicWitness map[string]interface{}) (bool, error) {
	// 解码 Base64 编码的证明
	proofBytes, err := base64.StdEncoding.DecodeString(proofB64)
	if err != nil {
		return false, err
	}

	// 反序列化证明
	proof := groth16.NewProof(ecc.BN254)
	reader := bytes.NewReader(proofBytes)
	if _, err := proof.ReadFrom(reader); err != nil {
		return false, err
	}

	// 创建公开见证
	// 从输入中提取值
	deviceIDStr := publicWitness["device_id"].(string)
	challengeStr := publicWitness["challenge"].(string)
	commitmentBig := publicWitness["commitment"].(*big.Int)
	responseBig := publicWitness["response"].(*big.Int)

	// 将字符串转换为 big.Int
	deviceIDBig := new(big.Int)
	deviceIDBig.SetString(deviceIDStr, 10)

	challengeBig := new(big.Int)
	challengeBig.SetString(challengeStr, 10)

	// 创建电路实例（只包含公开输入）
	assignment := &AuthCircuit{
		DeviceID:   deviceIDBig,
		Challenge:  challengeBig,
		Commitment: commitmentBig,
		Response:   responseBig,
	}

	// 创建公开见证
	witness, err := frontend.NewWitness(assignment, ecc.BN254.ScalarField(), frontend.PublicOnly())
	if err != nil {
		return false, err
	}

	// 验证证明
	publicWitnessOnly, err := witness.Public()
	if err != nil {
		return false, err
	}

	err = groth16.Verify(proof, vk, publicWitnessOnly)
	if err != nil {
		return false, err
	}

	return true, nil
}
